﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Adp.Core.Attribute;
using Adp;
using Adp.Common;
using Adp.Core.Services;
using System.Security.Cryptography;
using System.Net;
using Yqd.Enm;
using Yqd.Controllers;
using Yqd.Models;
using System.IO;
using System.Drawing;
using Newtonsoft.Json;

namespace Yqd.Core
{
    public class DdService
    {
        static string UnitCode = "";
        static string UnitName = "";
        YqdContext ctx;
        public DdService(YqdContext ctx)
        {
            this.ctx = ctx;
        }
        public string Get(UrlBuilder url, AccessTokenMode mode)
        {
            try
            {
                var wx = Config.AppSecret(mode);

                var header = new WebHeaderCollection();
                string timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");
                string nonceStr = GetTimeStamp() + new Random().Next(1000, 9999).ToString();
                var mac = "30";

                string rawstring = $"GET\n{timestamp}\n{nonceStr}\n{url.GetPath()}";
                var ps = url.GetParamString();
                if (ps.HasValue())
                {
                    rawstring += "\n" + ps;
                }
                var sign = encrypt(rawstring, wx.AppSecret);
                header.Add("X-Hmac-Auth-Timestamp", timestamp);
                header.Add("X-Hmac-Auth-Version", "1.0");
                header.Add("X-Hmac-Auth-Nonce", nonceStr);
                header.Add("apiKey", wx.AppKey);
                header.Add("X-Hmac-Auth-Signature", sign);
                try
                {
                    header.Add("X-Hmac-Auth-IP", Fn.GetIP());
                }
                catch
                {
                    header.Add("X-Hmac-Auth-IP", "123.156.65.12");
                }

                header.Add("X-Hmac-Auth-MAC", mac);
                var c = new CookieContainer();
                return Fn.Get(Config.Api(url.ToString()), Encoding.UTF8, header, ref c);
            }
            catch (Exception ex)
            {
                Adp.Logs.Error<DdService>("授权失败，access_token error: {0}", ex.Message);
            }
            return "";
        }

        private string encrypt(string message, string secret)
        {
            secret = secret ?? "";
            UTF8Encoding encoding = new UTF8Encoding();
            byte[] bytes = encoding.GetBytes(secret);
            byte[] buffer = encoding.GetBytes(message);
            using (HMACSHA256 hmacsha = new HMACSHA256(bytes))
            {
                return Convert.ToBase64String(hmacsha.ComputeHash(buffer));
            }
        }
        private long GetTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds);
        }

        public const string AccessTokenCachePath = "/Areas/Yqd/Configs/AccessToken.json";
        public string GetAccessToken(AccessTokenMode mode)
        {
            var wx = Config.AppSecret(mode);
            var CacheService = Fn.GetService<CacheService>();
            var token = CacheService.GetObject(AccessTokenCachePath)?["钉钉AccessToken_" + wx.AppKey];
            if (token == null || ((DateTime)token["expires_in"]) < DateTime.Now)
            {
                var url = UrlBuilder.Init("/gettoken.json");
                var i = Get(url, mode);
                Adp.Logs.Information<DdService>("授权信息，access_token {0}",i);
                if (string.IsNullOrEmpty(i))
                {
                    return "";
                }
                try
                {
                    var r = i.ToJObject();
                    if (r["success"].ToObject<bool>())
                    {
                        var ts = r["content"]["data"]["accessToken"].ToString();
                        token = CacheService.GetObject(AccessTokenCachePath, new JObject());
                        token["钉钉AccessToken_" + wx.AppKey] = JObject.FromObject(new
                        {
                            access_token = ts,
                            expires_in = DateTime.Now.AddSeconds(r["content"]["data"]["expiresIn"].ToObject<int>())
                        });
                        CacheService.SaveToFile(AccessTokenCachePath, token.ToString());
                        return ts;
                    }
                    else
                    {
                        Adp.Logs.Error<DdService>("access_token error: {0}", i);
                    }
                }
                catch (Exception ex)
                {
                    Adp.Logs.Error<DdService>("授权失败-error: {0}", ex.Message);
                }
                return "";
            }
            return token["access_token"].ToString();
        }

        public string GetAppUser(string auth_code)
        {
            var api = UrlBuilder.Init("/rpc/oauth2/dingtalk_app_user.json");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("auth_code", auth_code);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                try
                {
                    var employeeCode = r["content"]["data"]["employeeCode"].ToString();
                    return employeeCode;
                    //var su = ctx.Yqd_User.FirstOrDefault(it => it.EmployeeCode == employeeCode && it.Status == 用户状态.使用中);
                    //if (su != null)
                    //{
                    //    var unit = ctx.Yqd_Unit.FirstOrDefault(it => it.OrganizationCode == su.UnitCode);
                    //    string UnitCode = "", UnitName = "";
                    //    if (unit != null)
                    //    {
                    //        UnitCode = unit.UnitCode;
                    //        UnitName = unit.Name;
                    //    }
                    //    var user = new YqdUser
                    //    {
                    //        Role = new List<角色类型>(),
                    //        Permit = new List<权限清单>(),
                    //        Avatar = su.Avatar,
                    //        Name = su.Name,
                    //        AccountId = su.AccountId,
                    //        UnitCode = UnitCode,
                    //        UnitName = UnitName,
                    //        OrganizationCode = su.UnitCode,
                    //        EmployeeCode = su.EmployeeCode
                    //    };
                    //    if (!string.IsNullOrWhiteSpace(su.Roles))
                    //    {
                    //        user.Role = su.Roles.Split(",").Select(it => (角色类型)int.Parse(it)).ToList();
                    //    }
                    //    if (!string.IsNullOrWhiteSpace(su.PermitItem))
                    //    {
                    //        user.Permit = su.PermitItem.Split(",").Select(it => (权限清单)int.Parse(it)).ToList();
                    //    }
                    //    return user;
                    //}
                }
                catch
                {
                    return null;
                }
            }
            return null;
        }
        /// <summary>
        /// 获取员工基本信息
        /// </summary>
        /// <param name="employeeCode"></param>
        /// <param name="tenantId"></param>
        /// <returns></returns>
        public JObject GetEmployeeInfo(string employeeCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/employee/getEmployeeByCode");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("employeeCode", employeeCode);
            api.AddParam("tenantId", tenantId);
            var o = Post(api, AccessTokenMode.浙政钉通讯录);
            var r = o.ToJObject();
            Logs.Warning<DdService>("GetEmployeeInfo：" + o);
            if (r["success"].ToObject<bool>())
            {
                return (JObject)r["content"]["data"];
            }
            return null;
        }
        /// <summary>
        /// 获取组织信息
        /// </summary>
        /// <param name="organizationCode"></param>
        /// <param name="tenantId"></param>
        public JObject GetOrganizationInfo(string organizationCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/organization/getOrganizationByCode");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("organizationCode", organizationCode);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JObject)r["content"]["data"];
            }
            return null;
        }
        /// <summary>
        /// 单位员工列表  获取:组织下面的单位员工/职级/人员编制
        /// </summary>
        /// <param name="organizationCode"></param>
        /// <param name="tenantId"></param>
        public List<string> pageOrganizationEmployeeCodes(string organizationCode, int tenantId)
        {
            var arr = new List<string>();
            var i = 1;
            while (true)
            {
                var api = UrlBuilder.Init("/mozi/organization/pageOrganizationEmployeeCodes");
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
                api.AddParam("access_token", taken);
                api.AddParam("organizationCode", organizationCode);
                //api.AddParam("returnTotalSize", true);
                api.AddParam("pageNo", i++);
                api.AddParam("pageSize", 100);
                api.AddParam("tenantId", tenantId);
                var data = Post(api, AccessTokenMode.浙政钉通讯录);
                var r = data.ToJObject();
                Logs.Warning<DdService>("pageOrganizationEmployeeCodes：" + data);
                if (r["success"].ToObject<bool>())
                {
                    var d = r["content"]["data"];
                    if (d != null)
                    {
                        var l = d.Select(it => it.ToString()).ToList();
                        arr.AddRange(l);
                        if (l.Count < 100)
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    throw new Exception(r.ToString());
                }
            }
            return arr;
        }

        /// <summary>
        /// 单位员工列表  获取:组织下面的单位员工/职级/人员编制
        /// </summary>
        /// <param name="organizationCode"></param>
        /// <param name="tenantId"></param>
        public (List<string>, int) pageOrganizationEmployeeCodes(int PageNo, int Pagesize, string organizationCode, int tenantId)
        {
            var arr = new List<string>();
            var api = UrlBuilder.Init("/mozi/organization/pageOrganizationEmployeeCodes");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("organizationCode", organizationCode);
            api.AddParam("returnTotalSize", "true");
            api.AddParam("pageNo", PageNo);
            api.AddParam("pageSize", Pagesize);
            api.AddParam("employeePositionStatus", "A");
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            var totalCount = 0;
            Logs.Warning<DdService>(r.ToString());
            if (r["success"].ToObject<bool>())
            {
                var d = r["content"]["data"];
                if (d != null)
                {
                    arr.AddRange(d.Select(it => it.ToString()));
                }
                var count = r["content"]["totalSize"];
                if (count != null)
                {
                    totalCount = int.Parse(count.ToString());
                }
            }
            return (arr, totalCount);
        }


        /// <summary>
        /// 单位员工列表  获取:组织下面的单位员工/职级/人员编制
        /// </summary>
        /// <param name="organizationCode"></param>
        /// <param name="tenantId"></param>
        public JArray pageOrganizationEmployeePositions(string organizationCode, int tenantId)
        {
            var arr = new JArray();
            var i = 1;
            while (true)
            {
                var api = UrlBuilder.Init("/mozi/organization/pageOrganizationEmployeePositions");
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
                api.AddParam("access_token", taken);
                api.AddParam("employeeStatus", "A");
                api.AddParam("organizationCode", organizationCode);
                api.AddParam("pageNo", i++);
                api.AddParam("pageSize", 100);
                api.AddParam("returnTotalSize", true);
                api.AddParam("tenantId", tenantId);
                var data = Post(api, AccessTokenMode.浙政钉通讯录);
                var r = data.ToJObject();
                Logs.Warning<DdService>("pageOrganizationEmployeePositions：" + data);
                if (r["success"].ToObject<bool>())
                {
                    var d = r["content"]["data"];
                    if (d != null)
                    {
                        var l = d.Select(it => it.ToString()).ToList();
                        arr.Add(l);
                        if (l.Count < 100)
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    throw new Exception(r.ToString());
                }
            }

            //var api = UrlBuilder.Init("/mozi/organization/pageOrganizationEmployeePositions");
            //var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            //api.AddParam("access_token", taken);
            //api.AddParam("organizationCode", organizationCode);
            //api.AddParam("pageNo", 1);
            //api.AddParam("pageSize", 100);
            //api.AddParam("tenantId", tenantId);

            //var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            //Logs.Warning<DdService>("pageOrganizationEmployeePositions：" + r.ToString());
            //if (r["success"].ToObject<bool>())
            //{
            //    return (JArray)r["content"]["data"];
            //}
            return arr;
        }

        /// <summary>
        /// 获取通讯录权限范围 获取:组织的 organizationCode
        /// </summary>
        /// <param name="tenantId"></param>
        public JObject scopesV2(int tenantId)
        {
            var api = UrlBuilder.Init("/auth/scopesV2");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JObject)r["content"];
            }
            return null;
        }
        /// <summary>
        /// 根据员工Code获取员工的任职  获取:职务层次code表/人员角色
        /// </summary>
        /// <param name="tenantId"></param>
        public JObject listEmployeePositionsByEmployeeCode(string employeeCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/employee/listEmployeePositionsByEmployeeCode");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("employeeCode", employeeCode);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JObject)r["content"];
            }
            return null;
        }
        /// <summary>
        /// 枚举字典查询
        /// </summary>
        /// <param name="tenantId"></param>
        public JArray queryByPropertyCode(string propertyCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/enumdictionary/queryByPropertyCode");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("propertyCode", propertyCode);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JArray)r["content"]["data"];
            }
            return null;
        }

        public List<string> pageSearchOrganization(int tenantId)
        {
            var arr = new List<string>();
            var i = 1;
            while (true)
            {
                var api = UrlBuilder.Init("/mozi/fusion/pageSearchOrganization");
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
                api.AddParam("access_token", taken);
                api.AddParam("pageNo", i++);
                api.AddParam("pageSize", 100);
                api.AddParam("status", "A");
                api.AddParam("tenantId", tenantId);
                var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
                if (r["success"].ToObject<bool>())
                {
                    var d = r["content"]["data"];
                    if (d != null)
                    {
                        var l = d.Select(it => it.ToString()).ToList();
                        arr = arr.Concat(l).ToList();
                        if (l.Count < 100)
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    throw new Exception(r.ToString());
                }
            }
            return arr;
        }

        /// <summary>
        /// 分页获取下⼀级组织 Code 列表
        /// </summary>
        /// <param name="tenantId"></param>
        public List<string> pageSubOrganizationCodes(string organizationCode, int tenantId, bool checksub = false)
        {
            var arr = new List<string>();
            var i = 1;
            while (true)
            {
                var api = UrlBuilder.Init("/mozi/organization/pageSubOrganizationCodes");
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
                api.AddParam("access_token", taken);
                api.AddParam("organizationCode", organizationCode);
                api.AddParam("pageNo", i++);
                api.AddParam("pageSize", 100);
                api.AddParam("status", "A");
                api.AddParam("tenantId", tenantId);
                var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
                if (r["success"].ToObject<bool>())
                {
                    var d = r["content"]["data"];
                    if (d != null)
                    {
                        var l = d.Select(it => it.ToString()).ToList();
                        arr = arr.Concat(l).ToList();
                        if (l.Count < 100)
                        {
                            break;
                        }
                    }
                    if (d == null)
                    {
                        break;
                    }
                }
                else
                {
                    throw new Exception(r.ToString());
                }
                if (checksub)
                {
                    break;
                }
            }
            return arr;
        }

        /// <summary>
        /// 分页获取下⼀级组织 Code 批量根据员工Code获取员⼯账号ID
        /// </summary>
        /// <param name="tenantId"></param>
        public JObject listEmployeeAccountIds(string employeeCodes, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/employee/listEmployeeAccountIds");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("employeeCodes", employeeCodes);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>() && r["content"]["data"].Count() > 0)
            {
                return (JObject)r["content"]["data"][0];
            }
            return null;
        }
        public (List<string>, int) pageSearchEmployee(int PageNo, int Pagesize, string nameKeywords, int tenantId)
        {
            var arr = new List<string>();
            var api = UrlBuilder.Init("/mozi/fusion/pageSearchEmployee");
            var token = GetAccessToken(AccessTokenMode.浙政钉通讯录); 
            api.AddParam("access_token", token);
            api.AddParam("cascadeOrganizationCode", "GO_8ac50bba75c14c1589e2d3bef418ba87");
            api.AddParam("nameKeywords", nameKeywords);
            api.AddParam("pageNo", PageNo);
            api.AddParam("pageSize", Pagesize);
            api.AddParam("returnTotalSize", true);
            api.AddParam("status", "A");
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            var totalCount = 0;
            Logs.Warning<DdService>(r.ToString());
            if (r["success"].ToObject<bool>())
            {
                var d = r["content"]["data"];
                if (d != null)
                {
                    arr.AddRange(d.Select(it => it.ToString()));
                }
                var count = r["content"]["totalSize"];
                if (count != null)
                {
                    totalCount = int.Parse(count.ToString());
                }
            }
            return (arr, totalCount);
        }

        /// <summary>
        /// 获取用户头像
        /// </summary>
        /// <param name="mediaId"></param>
        public bool GenerateAvatar(string mediaId, string filename)
        {
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            var url = UrlBuilder.Init(Config.Api("/media/download"), false);
            url.AddParam("access_token", taken);
            url.AddParam("media_id", mediaId);
            var wx = Config.AppSecret(AccessTokenMode.浙政钉通讯录);
            var header = new WebHeaderCollection();
            string timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");
            string nonceStr = GetTimeStamp() + new Random().Next(1000, 9999).ToString();
            var mac = "30";
            string rawstring = $"GET\n{timestamp}\n{nonceStr}\n{url.GetPath()}";
            var ps = url.GetParamString();
            if (ps.HasValue())
            {
                rawstring += "\n" + ps;
            }
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url.ToString());
            req.Method = "GET";
            var sign = encrypt(rawstring, wx.AppSecret);
            req.Headers.Add("X-Hmac-Auth-Timestamp", timestamp);
            req.Headers.Add("X-Hmac-Auth-Version", "1.0");
            req.Headers.Add("X-Hmac-Auth-Nonce", nonceStr);
            req.Headers.Add("apiKey", wx.AppKey);
            req.Headers.Add("X-Hmac-Auth-Signature", sign);
            req.Headers.Add("X-Hmac-Auth-IP", Fn.GetIP());
            req.Headers.Add("X-Hmac-Auth-MAC", mac);
            req.CookieContainer = new CookieContainer();
            try
            {
                using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
                {
                    var stream = response.GetResponseStream();
                    FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write);
                    byte[] bytes = new byte[1024];
                    var size = stream.Read(bytes, 0, bytes.Length);
                    while (size > 0)
                    {
                        fileStream.Write(bytes, 0, size);
                        size = stream.Read(bytes, 0, bytes.Length);
                    }
                    response.Close();
                    stream.Close();
                    fileStream.Close();
                    return true;
                }
            }
            catch (Exception ex)
            {
                Fn.Log(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 获取应用可见性
        /// </summary>
        /// <param name="tenantId"></param>
        public void getAppUsedRange(string currentPage, int tenantId)
        {
            var api = UrlBuilder.Init("/openplatform/appcenter/getAppUsedRange");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("currentPage", currentPage);
            api.AddParam("tenantId", tenantId);
            //api.AddParam("status", "A");
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                var data = r["content"]["data"];
                //return (
                //    data["employeeCode"].ToString(),
                //    data["employeeName"].ToString(),
                //    data["status"].ToString(),              //状态
                //    data["empGender"].ToString(),           //姓别
                //    data["govEmpAvatar"].ToString(),        //头像
                //    data["empJobLevelCode"].ToString()      //职务等级
                //);
            }
            //return ("", "", "", "", "", "");
            return;
        }
        /// <summary>
        /// 添加应用可见性
        /// </summary>
        /// <param name="tenantId"></param>
        public void addAppUsedRange(string orgCodes, string accountIds, int tenantId)
        {
            var api = UrlBuilder.Init("/openplatform/appcenter/addAppUsedRange");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("orgCodes", orgCodes);
            api.AddParam("accountIds", accountIds);
            api.AddParam("tenantId", tenantId);
            //api.AddParam("status", "A");
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                var data = r["content"]["data"];
                //return (
                //    data["employeeCode"].ToString(),
                //    data["employeeName"].ToString(),
                //    data["status"].ToString(),              //状态
                //    data["empGender"].ToString(),           //姓别
                //    data["govEmpAvatar"].ToString(),        //头像
                //    data["empJobLevelCode"].ToString()      //职务等级
                //);
            }
            //return ("", "", "", "", "", "");
            return;
        }
        /// <summary>
        /// 删除应用可见性
        /// </summary>
        /// <param name="tenantId"></param>
        public void deleteAppUsedRange(string orgCodes, string accountIds, int tenantId)
        {
            var api = UrlBuilder.Init("/openplatform/appcenter/deleteAppUsedRange");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("orgCodes", orgCodes);
            api.AddParam("accountIds", accountIds);
            api.AddParam("tenantId", tenantId);
            //api.AddParam("status", "A");
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                var data = r["content"]["data"];
                //return (
                //    data["employeeCode"].ToString(),
                //    data["employeeName"].ToString(),
                //    data["status"].ToString(),              //状态
                //    data["empGender"].ToString(),           //姓别
                //    data["govEmpAvatar"].ToString(),        //头像
                //    data["empJobLevelCode"].ToString()      //职务等级
                //);
            }
            //return ("", "", "", "", "", "");
            return;
        }

        public string GetPropertyNameByCode(string type, string value)
        {
            return Env.Config.Init("Yqd", "枚举字典", type, value).First()?.Value ?? "";
        }

        /// <summary>
        /// DING API开放接口
        /// </summary>
        /// <param name="senderAccountId">发送者帐号ID</param>
        /// <param name="receiverAccountIds">接收者帐号ID，以“,”隔开</param>
        /// <param name="body">发送文本</param>
        public string DingSend(string senderAccountId, string receiverAccountIds, string body)
        {
            var api = UrlBuilder.Init("/gov/ding/isv/send.json", false);
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("body", JObject.FromObject(new
            {
                text = body
            }).ToString());
            api.AddParam("bodyType", "text");
            api.AddParam("creator", JObject.FromObject(new
            {
                accountId = senderAccountId
            }).ToString());
            api.AddParam("notifyType", "app");
            api.AddParam("receivers", JArray.FromObject(receiverAccountIds.Split(",").Select(it => new
            {
                accountId = it
            })).ToString());
            var config = Config.AppSecret(AccessTokenMode.浙政钉通讯录);
            api.AddParam("tenantId", config.TenantId);
            api.AddParam("textType", "plaintext");
            return Post(api, AccessTokenMode.浙政钉通讯录);
        }


        public string workRevoke(string bizMsgId)
        {
            try
            {
                string Ip = Fn.GetIP();
                var api = UrlBuilder.Init("/message/revoke", false);
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);

                api.AddParam("bizMsgId", bizMsgId);
                api.AddParam("msgApp", "cy_yqd");
                api.AddParam("msgType", "workNotification");


                var config = Config.AppSecret(AccessTokenMode.浙政钉通讯录);
                api.AddParam("tenantId", config.TenantId);

                Logs.Information<DdService>("开始post,参数{0}", JsonConvert.SerializeObject(api));
                string result = Post(api, AccessTokenMode.浙政钉通讯录, Ip);
                Logs.Information<RankService>($"钉消息撤回响应：{result}");
                return result;
            }
            catch (Exception e)
            {
                Logs.Error<DdService>("workNotification 莫名其妙发送报错{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);
                return string.Format("workNotification 莫名其妙发送报错{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);

            }

        }

        public string workNotification(string organizationCodes, string receiverIds, string bizMsgId, string msg, string IP)
        {
            try
            {
                var api = UrlBuilder.Init("/message/workNotification", false);
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);

                if (string.IsNullOrWhiteSpace(organizationCodes) && string.IsNullOrWhiteSpace(receiverIds))
                {
                    return "接收对象不能为空";
                }

                if (!string.IsNullOrWhiteSpace(bizMsgId))
                {
                    api.AddParam("bizMsgId", bizMsgId);
                }

                api.AddParam("msg", msg);


                Logs.Information<RankService>($"钉消息推送模板：{msg}");
                if (!string.IsNullOrWhiteSpace(organizationCodes))
                {
                    api.AddParam("organizationCodes", organizationCodes);
                }

                if (!string.IsNullOrWhiteSpace(receiverIds))
                {
                    api.AddParam("receiverIds", receiverIds);
                }
                var config = Config.AppSecret(AccessTokenMode.浙政钉通讯录);
                api.AddParam("tenantId", config.TenantId);

                Logs.Information<DdService>($"开始post,参数{organizationCodes},{receiverIds},{bizMsgId},{msg},{config.TenantId}");
                return Post(api, AccessTokenMode.浙政钉通讯录, IP);
            }
            catch (Exception e)
            {
                Logs.Error<DdService>("workNotification 莫名其妙发送报错{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);
                return string.Format("workNotification 莫名其妙发送报错{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);

            }

        }

        /// <summary>
        /// 获取单位
        /// </summary>
        /// <param name="OrganizationCode"></param>
        /// <returns></returns>
        private (string UnitCode, string UnitName) GetUnit(string OrganizationCode)
        {
            if (string.IsNullOrEmpty(OrganizationCode))
            {
                return ("", "");
            }
            using (var ctx = new YqdContext())
            {
                var org = ctx.Yqd_Department.FirstOrDefault(it => it.OrganizationCode == OrganizationCode);
                if (org == null)
                {
                    return ("", "");
                }
                if (org.TypeCode == "GOV_UNIT")
                {
                    UnitCode = org.OrganizationCode;
                    UnitName = org.Name;
                    return (UnitCode, UnitName);
                }
                if (org.TypeCode == "GOV_HOLLOW_STRIP_NODE")
                {
                    return (UnitCode, UnitName);
                }
                return GetUnit(org.ParentCode);
            }
        }

        /// <summary>
        /// 递归获取所有子部门
        /// </summary>
        /// <param name="parentOrganizationCode"></param>
        /// <param name="ids"></param>
        /// <returns></returns>
        private List<string> GetChildIds(string parentOrganizationCode, List<string> ids)
        {
            using (var ctx = new YqdContext())
            {
                var org = ctx.Yqd_Department.Where(it => it.ParentCode == parentOrganizationCode).ToList();
                foreach (var item in org)
                {
                    ids.Add(item.OrganizationCode);
                    GetChildIds(item.OrganizationCode, ids);
                }
                return ids;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="receiverIds"></param>
        /// <param name="headTitle"></param>
        /// <param name="TaskID"></param>
        /// <param name="TaskName">任务名称</param>
        /// <param name="text">任务详情</param>
        /// <param name="IsDd"></param>
        /// <param name="superId"></param>
        /// <param name="pushStep"></param>
        /// <param name="unitCode"></param>
        /// <param name="employeeCode"></param>
        /// <param name="employeeName"></param>
        /// <returns></returns>
        public string Notification(List<string> receiverIds, string headTitle, string TaskID, string TaskName, string text, bool IsDd = false, int superId = 0, 推送流程 pushStep = 推送流程.领导钉办, string unitCode = "", string employeeCode = "", List<string> employeeNames = null)
        {
            //var receiverIds = UnitCode;
            if (receiverIds == null || receiverIds.Count == 0)
            {
                receiverIds = new List<string>();
            }

            var unit = ctx.Yqd_Unit.FirstOrDefault(it => it.UnitCode == unitCode);
            if (unit != null)
            {
                unitCode = unit.OrganizationCode;
            }

            List<string> unitList = new List<string>();
            var parentUnit = GetUnit(unitCode);//取单位
            if (!string.IsNullOrEmpty(parentUnit.UnitCode))
            {
                unitList = GetChildIds(parentUnit.UnitCode, new List<string>() { parentUnit.UnitCode });
            }

            Logs.Information<DdService>($"推送的部门单位列表:{string.Join(",", unitList)}，推送当前部门:{unitCode}");
            if (pushStep == 推送流程.领导钉办)
            {
                //权限：接收领导钉办
                if (unitList.Any())
                {
                    int permit = (int)权限清单.接收领导钉办督导消息;
                    var user = ctx.Yqd_User.Where(it => unitList.Contains(it.UnitCode) && it.AccountId > 0 && it.Status == 用户状态.使用中 && it.PermitItem.Contains(permit.ToString())).ToList();
                    receiverIds.AddRange(user.Select(it => it.AccountId.ToString()));

                    //var userMs = ctx.Yqd_User.Where(it => unitList.Contains(it.UnitCode) && it.AccountId > 0 && it.Status == 用户状态.使用中 && it.Roles.Contains("," + (int)角色类型.领导秘书 + ",")).ToList();
                    //receiverIds.AddRange(userMs.Select(it => it.AccountId.ToString()));
                }


                //领导秘书
                var userMS = ctx.Yqd_User.SingleOrDefault(it => it.EmployeeCode == employeeCode);
                if (userMS != null)
                {
                    if (!string.IsNullOrEmpty(userMS.RealtionEmployeeCode))
                    {
                        var arrayEmployee = userMS.RealtionEmployeeCode.Split(",");
                        var userList = ctx.Yqd_User.Where(it => it.AccountId > 0 && it.Status == 用户状态.使用中 && arrayEmployee.Contains(it.EmployeeCode));

                        receiverIds.AddRange(userList.Select(it => it.AccountId.ToString()));
                    }
                }

            }
            else if (pushStep == 推送流程.领导督导)
            {
                //if (unitList.Any())
                //{
                //todo:督导意见发送给关联秘书
                var user = ctx.Yqd_User.SingleOrDefault(it => it.EmployeeCode == employeeCode);
                if (user != null)
                {
                    if (!string.IsNullOrEmpty(user.RealtionEmployeeCode))
                    {
                        var arrayEmployee = user.RealtionEmployeeCode.Split(",");
                        var userList = ctx.Yqd_User.Where(it => it.AccountId > 0 && it.Status == 用户状态.使用中 && arrayEmployee.Contains(it.EmployeeCode));

                        receiverIds.AddRange(userList.Select(it => it.AccountId.ToString()));
                    }
                }
                //}
            }
            else if (pushStep == 推送流程.交办)
            {
                //权限：接收任务交办
                if (unitList.Any())
                {
                    int permit = (int)权限清单.接收任务交办;

                    var user = ctx.Yqd_User.Where(it => unitList.Contains(it.UnitCode) && it.AccountId > 0 && it.Status == 用户状态.使用中 && it.PermitItem.Contains(permit.ToString())).ToList();
                    receiverIds.AddRange(user.Select(it => it.AccountId.ToString()));
                }
            }
            else if (pushStep == 推送流程.工作流转)
            {
                //推送交办人
            }
            else if (pushStep == 推送流程.工作退回)
            {
                //权限：接收任务交办退回
                if (unitList.Any())
                {
                    int permit = (int)权限清单.接收任务交办退回;

                    var user = ctx.Yqd_User.Where(it => unitList.Contains(it.UnitCode) && it.AccountId > 0 && it.Status == 用户状态.使用中 && it.PermitItem.Contains(permit.ToString())).ToList();
                    receiverIds.AddRange(user.Select(it => it.AccountId.ToString()));
                }

                if (employeeNames != null && employeeNames.Any())
                {
                    var user = ctx.Yqd_User.Where(it => unitList.Contains(it.UnitCode) && it.AccountId > 0 && it.Status == 用户状态.使用中 && employeeNames.Contains(it.Name)).ToList();
                    receiverIds.AddRange(user.Select(it => it.AccountId.ToString()));
                }
            }
            else if (pushStep == 推送流程.内部流转)
            {
                //推送流转人
            }
            else if (pushStep == 推送流程.任务交办预警和滞后)
            {
                //推送接收预警和滞后
                //try
                //{
                if (unitList.Any())
                {
                    try
                    {
                        int permit = (int)权限清单.接收预警和滞后;
                        var user = ctx.Yqd_User.Where(it => unitList.Contains(it.UnitCode) && it.AccountId > 0 && it.Status == 用户状态.使用中 && it.PermitItem.Contains(permit.ToString())).ToList();
                        receiverIds.AddRange(user.Select(it => it.AccountId.ToString()));
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                }

                if (employeeNames != null && employeeNames.Any())
                {
                    var user = ctx.Yqd_User.Where(it => unitList.Contains(it.UnitCode) && it.AccountId > 0 && it.Status == 用户状态.使用中 && employeeNames.Contains(it.Name)).ToList();
                    receiverIds.AddRange(user.Select(it => it.AccountId.ToString()));
                }
                //}
                //catch (Exception ex)
                //{
                //    Logs.Information<DdService>("有错误:" + ex.Message);
                //}
            }


            Logs.Information<DdService>("人员名单:" + string.Join(",", receiverIds));
            if (receiverIds.Count == 0)
            {
                Logs.Information<DdService>("无人员名单");
                return "无人员名单";
            }
            var t = receiverIds.GroupBy(x => x).ToList();
            var url = "https://yqd.hd.yw.gov.cn/auth?tID=" + TaskID + "&dd=" + (IsDd ? 1 : 0) + "&sID=" + superId;
            var msg = JObject.FromObject(new
            {
                msgtype = "oa",
                oa = JObject.FromObject(new
                {
                    message_url = url + "&dev=" + (int)设备平台.手机端,
                    pc_message_url = url,
                    head = JObject.FromObject(new
                    {
                        bgcolor = "000000",
                        text = headTitle

                    }),
                    body = JObject.FromObject(new
                    {
                        title = TaskName,
                        content = text + "任务详情见\"义起督\"浙政钉应用。打开方式：浙政钉电脑版 - 工作台 - 义乌市 - 数字政府 - 义起督"
                    })
                })
            }).ToString();

            //var random = new byte[2];
            //var rng = new RNGCryptoServiceProvider();
            //rng.GetNonZeroBytes(random);
            //var sb = new StringBuilder(4);
            //for (var i = 0; i < random.Length; i++)
            //{
            //    sb.Append(string.Format("{0:X2}", random[i]));
            //}

            var Ip = "123.156.65.12";
            try
            {
                Ip = Fn.GetIP();
            }
            catch (Exception)
            {
                Ip = "123.156.65.12";
            }
            return workNotification("", string.Join(",", t.Select(x => x.Key).ToList()), Guid.NewGuid().ToString().Replace("-", ""), msg, Ip);
        }

        public string GetNotification_OA(Yqd_Rank rank)
        {

            var arr = new ArrayList();
            arr.Add(new
            {
                key = "效能指数",
                value = rank.Score
            });
            if (rank.UnitCode != "330782000000")
            {
                arr.Add(new
                {
                    key = "全市排名",
                    value = rank.UnitCode == "330782000000" ? "--" : rank.Tactic.ToString()
                });

            }

            //var dt=DateTime
            var msg = JObject.FromObject(new
            {
                msgtype = "oa",
                oa = JObject.FromObject(new
                {
                    message_url = "https://yqd.hd.yw.gov.cn/gzd#/workNotification/UnitRank?bizmsgid=" + rank.RankID,
                    pc_message_url = "https://yqd.hd.yw.gov.cn/gzd#/workNotification/UnitRank?bizmsgid=" + rank.RankID,
                    head = JObject.FromObject(new
                    {
                        bgcolor = "000000",
                        text = "部门效能评价报告"

                    }),
                    body = JObject.FromObject(new
                    {
                        title = rank.Name + "(" + DateTime.Now.ToString("yyyy-MM-dd") + ")",
                        form = JArray.FromObject(arr),
                        content = "滞后事项" + rank.ZH + "项，预警事项" + rank.YJ + "项，正常事项" + rank.ZC + "项，已完成事项" + rank.WC + "项。"
                    })

                })
            }).ToString();

            return msg;
        }
        public string GetNotification_Text(string Msg)
        {

            var msg = JObject.FromObject(new
            {
                msgtype = "text",
                text = JObject.FromObject(new
                {
                    content = Msg
                })
            }).ToString();

            return msg;
        }

        public string Post(UrlBuilder url, AccessTokenMode mode)
        {
            return Post(url, mode, "");

        }

        public string Post(UrlBuilder url, AccessTokenMode mode, string IP)
        {

            try
            {
                var header = new WebHeaderCollection();
                string timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");
                string nonceStr = GetTimeStamp() + new Random().Next(1000, 9999).ToString();
                var mac = "30";

                string rawstring = $"POST\n{timestamp}\n{nonceStr}\n{url.GetPath()}";
                var p = "";

                foreach (var item in url.Params)
                {
                    p += $"&{item.Name}={(item.Value)}";
                }
                if (url.Params.Count > 0)
                {
                    rawstring += "\n" + p.Trim('&');
                }

                var wx = Config.AppSecret(mode);
                var sign = encrypt(rawstring, wx.AppSecret);
                header.Add("X-Hmac-Auth-Timestamp", timestamp);
                header.Add("X-Hmac-Auth-Version", "1.0");
                header.Add("X-Hmac-Auth-Nonce", nonceStr);
                header.Add("apiKey", wx.AppKey);
                header.Add("X-Hmac-Auth-Signature", sign);
                header.Add("X-Hmac-Auth-IP", string.IsNullOrWhiteSpace(IP) ? "123.156.65.12" : IP);
                header.Add("X-Hmac-Auth-MAC", mac);
                var c = new CookieContainer();
                p = "";
                foreach (var item in url.Params)
                {
                    p += $"&{item.Name}={System.Web.HttpUtility.UrlEncode(item.Value)}";
                }
                string result = Fn.Post(Config.Api(url.GetUrl()), p.Trim('&'), Encoding.UTF8, header, ref c);

                Logs.Information<DdService>($"post请求结果{result}");
                return result;
            }
            catch (Exception e)
            {
                Logs.Error<DdService>("Post莫名其妙报错了{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);
                return string.Format(" Post莫名其妙报错了{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);
            }



        }
    }
}
